﻿using System;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using ADEVSO.Util;
using SmartParking.Bussiness;
using SmartParking.Data.Entities;

namespace SmartParking.Web.Models
{
    //public class ReservationsModel
    //{
    //    private HttpContextBase _httpContext = null;

    //    public ReservationModel Reservation;
    //    //public ReservationListModel Reservations;
    //    public string ErrorMessage;
    //    public string ReservationsHtml;
                
    //    public ReservationsModel(HttpContextBase httpContext)
    //    {
    //        _httpContext = httpContext;
    //        Reservation = new ReservationModel();
    //        RefreshReservations();
    //        //Reservations = new ReservationListModel(httpContext);
    //    }

    //    public bool HasError { get { return !String.IsNullOrEmpty(ErrorMessage); } }

    //    public List<ReservationListItemModel> Reservations { get; private set; }

    //    public void RefreshReservations()
    //    {
    //        Reservations = new List<ReservationListItemModel>();
    //        var liveReservations = ReservationsManager.GetLiveReservations(_httpContext.ApplicationInstance.Application, _httpContext.Session);
    //        Reservations.AddRange(liveReservations.Select(item => ReservationListModel.CopyReservationData(item)));
    //    }
    //}

    public class OrderModel
    {
        [Required]
        [Display(Name = "Parqueo")]
        public int ParkingId { get; set; }

        [Required]
        [Display(Name = "Zona")]
        public int ParkingZoneId { get; set; }

        [Display(Name = "Precio")]
        [DisplayFormat(DataFormatString = "{0:C2}")]
        public decimal PriceHour { get; set; }

        [Display(Name = "Comisión")]
        [DisplayFormat(DataFormatString = "{0:C2}")]
        public decimal Commission { get; set; }

        [Required]
        [Display(Name = "Fecha")]
        public string Date { get; set; }

        [Required]
        [Display(Name = "Entrada")]
        public int StartHour { get; set; }

        [Required]
        [Display(Name = "Salida")]
        public int EndHour { get; set; }

        [Required]
        [StringLength(10)]
        [Display(Name = "Placa")]
        public string CarPlate { get; set; }

        public List<SelectListItem> Parkings { get; set; }
        public List<SelectListItem> ParkingZones { get; set; }
        public List<SelectListItem> OpenHours { get; set; }
        public List<SelectListItem> CloseHours { get; set; }

        public OrderModel()
        {
            Refresh();
        }

        /// <summary>
        /// Return an order detail from a model
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static OrderDetail CreateOrderDetail(ReservationModel model)
        {
            var reservation = new OrderDetail();
            reservation.ParkingID = model.ParkingId;
            reservation.ParkingZoneID = model.ParkingZoneId;
            var date = Convert.ToDateTime(model.Date, new CultureInfo("es-CR"));
            var hour = ((Hour)model.StartHour);
            var time = new TimeSpan(hour.GetHour(), hour.GetMinutes(), 0);
            reservation.ReservationStartDateTime = date.Add(time);
            hour = ((Hour)model.EndHour);
            time = new TimeSpan(hour.GetHour(), hour.GetMinutes(), 0);
            reservation.ReservationEndDateTime = date.Add(time);
            reservation.CarPlate = model.CarPlate;
            return reservation;
        }

        /// <summary>
        /// Refresh model
        /// </summary>
        public void Refresh()
        {
            RefreshParkings();
            RefreshParkingZones();
            RefreshPriceHourAndCommission();
            RefreshOpenHours();
            RefreshCloseHours();
        }

        private void RefreshParkings()
        {
            var items = new List<SelectListItem>();
            items.Add(new SelectListItem() { Text = "Seleccione un parqueo...", Value = "0", Selected = ParkingId == 0 }); //Add empty item
            if (ParkingId == 0)
            {
                var parkings = ParkingManager.GetParkingsToWebReservations();
                items.AddRange(parkings.Select(p => new SelectListItem() {Text = p.Name.Trim(), Value = Convert.ToString(p.ParkingID).Trim(), Selected = p.ParkingID == ParkingId}));
                ParkingZoneId = 0;
            }
            Parkings = items;
        }

        private void RefreshParkingZones()
        {
            var items = new List<SelectListItem>();
            if (ParkingId != 0)
            {
                items.Add(new SelectListItem() { Text = "Seleccione una zona de parqueo...", Value = "0", Selected = ParkingZoneId == 0 }); //Add empty item
                if (ParkingZoneId == 0)
                {
                    var parkingZones = ParkingManager.GetParkingZonesToWebReservations(ParkingId);
                    items.AddRange(parkingZones.Select(p => new SelectListItem() {Text = p.Name.Trim(), Value = Convert.ToString(p.ParkingZoneID).Trim(), Selected = ParkingZoneId == p.ParkingZoneID}));
                    StartHour = 0;
                }
            }
            ParkingZones = items;
        }

        private void RefreshPriceHourAndCommission()
        {
            if (ParkingId != 0 && ParkingZoneId != 0)
            {                
                var parkingZoneFare = ParkingManager.GetParkingZoneWebFare(ParkingZoneId);
                PriceHour = parkingZoneFare.PriceHour;
                Commission = parkingZoneFare.ParkingZone.WebCommisionAmount;
            }
        }

        private void RefreshOpenHours()
        {
            var items = new List<SelectListItem>();
            if (ParkingId != 0 && ParkingZoneId != 0)
            {                
                items.Add(new SelectListItem() { Text = "Seleccione una hora de entrada...", Value = "0", Selected = StartHour == 0 }); //Add empty item
                if ((Hour)StartHour == Hour.None)
                {
                    var parkingZone = ParkingManager.GetParkingZone(ParkingZoneId);
                    var hours = Hour.AM0100.RangeHours(parkingZone.OpenHour.ToHour(), parkingZone.CloseHour.ToHour(), parkingZone.AllowHalfHour);
                    items.AddRange(hours.Select(h => new SelectListItem() {Text = h.ToStringHour(), Value = Convert.ToString(Convert.ToInt32(h)), Selected = (Hour) StartHour == h}));
                    EndHour = 0;
                }                
            }
            OpenHours = items;
        }

        private void RefreshCloseHours()
        {
            var items = new List<SelectListItem>();
            if (ParkingId != 0 && ParkingZoneId != 0 && (Hour)StartHour != Hour.None)
            {                
                items.Add(new SelectListItem() { Text = "Seleccione una hora de salida...", Value = "0", Selected = EndHour == 0 }); //Add empty item
                if ((Hour)StartHour != Hour.None && (Hour)EndHour == Hour.None)
                {
                    var parkingZone = ParkingManager.GetParkingZone(ParkingZoneId);
                    var hours = Hour.AM0100.RangeHours((Hour)StartHour + 1, parkingZone.CloseHour.ToHour(), parkingZone.AllowHalfHour);
                    items.AddRange(hours.Select(h => new SelectListItem() {Text = h.ToStringHour(), Value = Convert.ToString(Convert.ToInt32(h)), Selected = (Hour) EndHour == h}));
                }                
            }
            CloseHours = items;
        }
    }

    public class OrderListItemModel
    {
        public string Id { get; set; }
        public string Group { get; set; }
        public string UserId { get; set; }
        public string Date { get; set; }
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:G2}")]
        public string Amount { get; set; }
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:G2}")]
        public string Comission { get; set; }
        public bool IsReservation { get; set; }
        public string PaymentType { get; set; }
    }

    public class OrderListModel
    {
        public string ViewTitle { get; private set; }
        public string ItemView { get; private set; }
        public string ListTitle { get; private set; }
        public List<OrderListItemModel> Orders { get; private set; }
        public bool ReadOnly { get; private set; }
        public string EmptyMessage { get; private set; }

        public OrderListModel(bool readOnly = false, string email = "", string viewTitle = "")
        {
            ViewTitle = viewTitle;
            ListTitle = "";
            ItemView = "Order";
            var userId = email == String.Empty ? -1 : SecurityManager.GetUser(email).UserID;
            Orders = ReservationsManager.GetOrders(userId).Select(item => CopyOrderData(item)).ToList();
            ReadOnly = readOnly;
            EmptyMessage = "No se encontraron ordenes";
        }

        internal static OrderListItemModel CopyOrderData(Order order, string group = "")
        {
            var result = new OrderListItemModel
                {
                    Id = order.OrderID.Trim(),
                    Group = group,
                    UserId = order.UserID.HasValue ? order.UserID.Value.ToString() : String.Empty,
                    Date = order.DateTime.ToString("dd/MM/yyyy"),
                    Amount = order.TotalAmount.ToString(),
                    Comission = order.TotalCommission.ToString(),
                    IsReservation = order.IsReservation,
                    PaymentType = order.PaymentType.GetPaymentTypeName()
                };
            return result;
        }        
    }
}